import { getPool } from '../database/db.js';
import { log } from '../utils/logger.js';

export class Session {
  /**
   * 创建新会话（同时使旧会话失效，实现单用户在线）
   */
  static async create(userId, token, ipAddress, userAgent, expiresAt) {
    const pool = getPool();
    const connection = await pool.getConnection();
    
    try {
      await connection.beginTransaction();
      
      // 使该用户的所有旧会话失效
      const [deactivated] = await connection.execute(
        'UPDATE user_sessions SET is_active = 0 WHERE user_id = ? AND is_active = 1',
        [userId]
      );
      
      if (deactivated.affectedRows > 0) {
        log.auth(`用户的旧会话已失效`, { userId, count: deactivated.affectedRows });
      }

      // 创建新会话
      const [result] = await connection.execute(
        'INSERT INTO user_sessions (user_id, token, ip_address, user_agent, expires_at) VALUES (?, ?, ?, ?, ?)',
        [userId, token, ipAddress, userAgent, expiresAt]
      );
      
      await connection.commit();
      
      log.auth(`新会话创建成功`, { 
        userId, 
        sessionId: result.insertId,
        ip: ipAddress 
      });
      
      return result.insertId;
    } catch (error) {
      await connection.rollback();
      log.error('创建会话失败', { error: error.message, userId });
      throw error;
    } finally {
      connection.release();
    }
  }

  /**
   * 根据token查找会话
   */
  static async findByToken(token) {
    const pool = getPool();
    try {
      const [rows] = await pool.execute(
        'SELECT * FROM user_sessions WHERE token = ? AND is_active = 1 AND expires_at > NOW()',
        [token]
      );
      return rows[0] || null;
    } catch (error) {
      log.error('查询会话失败', { error: error.message });
      throw error;
    }
  }

  /**
   * 使会话失效（登出）
   */
  static async deactivate(token) {
    const pool = getPool();
    try {
      const [result] = await pool.execute(
        'UPDATE user_sessions SET is_active = 0 WHERE token = ?',
        [token]
      );
      
      if (result.affectedRows > 0) {
        log.auth('会话已注销');
      }
      
      return result.affectedRows > 0;
    } catch (error) {
      log.error('会话注销失败', { error: error.message });
      throw error;
    }
  }

  /**
   * 使用户的所有会话失效
   */
  static async deactivateAllByUser(userId) {
    const pool = getPool();
    try {
      const [result] = await pool.execute(
        'UPDATE user_sessions SET is_active = 0 WHERE user_id = ? AND is_active = 1',
        [userId]
      );
      
      log.auth(`用户的所有会话已注销`, { userId, count: result.affectedRows });
      return result.affectedRows;
    } catch (error) {
      log.error('批量注销会话失败', { error: error.message, userId });
      throw error;
    }
  }

  /**
   * 清理过期会话
   */
  static async cleanupExpired() {
    const pool = getPool();
    try {
      const [result] = await pool.execute(
        'DELETE FROM user_sessions WHERE expires_at < NOW() OR is_active = 0'
      );
      
      if (result.affectedRows > 0) {
        log.system(`清理过期会话`, { count: result.affectedRows });
      }
      
      return result.affectedRows;
    } catch (error) {
      log.error('清理过期会话失败', { error: error.message });
      throw error;
    }
  }

  /**
   * 获取用户的活跃会话
   */
  static async getActiveByUser(userId) {
    const pool = getPool();
    try {
      const [rows] = await pool.execute(
        'SELECT * FROM user_sessions WHERE user_id = ? AND is_active = 1 AND expires_at > NOW() ORDER BY created_at DESC',
        [userId]
      );
      return rows;
    } catch (error) {
      log.error('查询活跃会话失败', { error: error.message, userId });
      throw error;
    }
  }

  /**
   * 更新会话的最后活动时间
   */
  static async updateLastActivity(token, newExpiresAt) {
    const pool = getPool();
    try {
      await pool.execute(
        'UPDATE user_sessions SET expires_at = ? WHERE token = ? AND is_active = 1',
        [newExpiresAt, token]
      );
    } catch (error) {
      log.error('更新会话活动时间失败', { error: error.message });
      throw error;
    }
  }
}

// 定期清理过期会话（每小时执行一次）
setInterval(() => {
  Session.cleanupExpired();
}, 60 * 60 * 1000);
